package com.rightrule;

import com.spire.pdf.PdfDocument;
import com.spire.pdf.graphics.fonts.PdfUsedFont;
import com.spire.pdf.utilities.PdfTable;
import com.spire.pdf.utilities.PdfTableExtractor;
import com.sun.xml.internal.messaging.saaj.util.ByteOutputStream;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
import org.apache.pdfbox.pdmodel.*;
import org.apache.pdfbox.pdmodel.font.PDType0Font;
import org.junit.jupiter.api.Test;

import java.awt.GraphicsEnvironment;
import java.io.*;

import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.util.StringUtils;
import technology.tabula.*;
import technology.tabula.extractors.SpreadsheetExtractionAlgorithm;

import java.util.*;
import java.util.List;

@SpringBootTest
@Slf4j
public class pdftest {


    @Test
    public void aada() throws IOException {
        InputStream resourceAsStream = getClass().getClassLoader().getResourceAsStream("a1.pdf");

//        InputStream aaa1 = aaa();

        // 打印当前的字体环境
        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();


        PdfDocument pdf = new PdfDocument();
        PdfDocument.setCustomFontsFolders("src/main/resources/SerifBold.ttf");
//        pdf.loadFromFile("src/main/resources/a1.pdf");
        pdf.loadFromStream(resourceAsStream);
        PdfUsedFont[] usedFonts = pdf.getUsedFonts();

        for (PdfUsedFont usedFont : usedFonts) {
            System.out.println(usedFont);
        }

        PdfTableExtractor extractor = new PdfTableExtractor(pdf);

        for (int i = 0; i < pdf.getPages().getCount(); i++) {
            PdfTable[] pdfTables = extractor.extractTable(i);
            if (pdfTables != null && pdfTables.length > 0) {
                for (PdfTable pdfTable : pdfTables) {
                    for (int row = 0; row < pdfTable.getRowCount(); row++) {
                        for (int column = 0; column < pdfTable.getColumnCount(); column++) {
                            String text = pdfTable.getText(row, column);
                            System.out.println(text);
                        }
                    }
                }
            }
        }
    }


    public InputStream aaa() throws IOException {
        InputStream resourceAsStream = getClass().getClassLoader().getResourceAsStream("a1.pdf");

        PDDocument document = PDDocument.load(resourceAsStream);

        int numberOfPages = document.getNumberOfPages();
        for (int i = 0; i < numberOfPages; i++) {
            PDPage page = document.getPage(i);

            InputStream aaa = getClass().getClassLoader().getResourceAsStream("SerifBold.ttf");


            PDPageContentStream contentStream = new PDPageContentStream(document, page);

            PDType0Font font = PDType0Font.load(document, aaa);
            contentStream.setFont(font, 12);
            contentStream.close();
        }

        ByteOutputStream byteOutputStream = new ByteOutputStream();
        document.save(byteOutputStream);
        document.close();

        return convertOutputStreamToInputStream(byteOutputStream);

    }



    public static InputStream convertOutputStreamToInputStream(OutputStream outputStream) throws IOException {
        // 首先，我们需要将 OutputStream 中的数据写入一个字节数组
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

        // 假设我们有一个方法可以将数据写入提供的 OutputStream
        writeDataToStream(outputStream); // 这里应该替换为实际写入数据的逻辑

        // 但是在这个例子中，我们直接将 byteArrayOutputStream 当作 outputStream 使用
        // 因此，我们需要先将 byteArrayOutputStream 的内容复制到一个新的字节数组中
        byte[] data = byteArrayOutputStream.toByteArray();

        // 然后，我们可以使用这个字节数组来创建一个 ByteArrayInputStream，它是一个 InputStream
        InputStream inputStream = new ByteArrayInputStream(data);

        // 注意：这里我们返回了 inputStream，但 byteArrayOutputStream 仍然可以被关闭（如果不需要它了）
        // byteArrayOutputStream.close(); // 这一步在这个例子中不是必需的，因为我们不再需要写入数据

        return inputStream;
    }

    // 这是一个示例方法，用于模拟向 OutputStream 写入数据
    private static void writeDataToStream(OutputStream outputStream) throws IOException {
        String data = "This is some data to be converted to an InputStream.";
        outputStream.write(data.getBytes());
        outputStream.flush(); // 确保所有数据都被写出
    }




    private static final SpreadsheetExtractionAlgorithm SPREADSHEEET_EXTRACTION_ALGORITHM = new SpreadsheetExtractionAlgorithm();

    @Test
    public void aadaqwq() {
        InputStream resourceAsStream = getClass().getClassLoader().getResourceAsStream("a1.pdf");

        List<String> strings = parsePdfTableForTasks(resourceAsStream, 1);
        strings.forEach(System.out::println);

    }


    public static List<String> parsePdfTableForTasks(InputStream input, Integer customStart) {
        List<String> resultStr = new ArrayList<>(); // 存储解析后的JSON数组
        try (PDDocument document = PDDocument.load(input)) {
            // 获取页面迭代器
            PageIterator pi = new ObjectExtractor(document).extract();
            // 遍历所有页面
            while (pi.hasNext()) {
                // 获取当前页
                Page page = pi.next();
                // 解析页面上的所有表格
                List<Table> tableList = SPREADSHEEET_EXTRACTION_ALGORITHM.extract(page);
                // 遍历所有表格
                for (Table table : tableList) {
                    // 获取表格中的每一行
                    List<List<RectangularTextContainer>> rowList = table.getRows();
                    // 遍历所有行并获取每个单元格信息
                    for (int rowIndex = customStart; rowIndex < rowList.size(); rowIndex++) {
                        // 获取行中的每个单元格
                        List<RectangularTextContainer> cellList = rowList.get(rowIndex);
                        for (RectangularTextContainer rectangularTextContainer : cellList) {
                            String text = rectangularTextContainer.getText();
                            System.out.println(text);
                        }
                    }
                }
            }
        } catch (IOException e) {
            log.error("读取PDF错误:{}", e.getMessage());
        } finally {
//            THREAD_LOCAL.remove();
        }
        return resultStr;
    }


    /**
     * 读取PDF方法
     *
     * @param filePath PDF的全路径
     * @return PDF内容
     */
    public static String readPDFcontentByFilePath(String filePath) {
        try {
            String[] argsa = new String[]{"-f=JSON", "-p=1", filePath, "-l"};
            CommandLineParser parser = new DefaultParser();
            CommandLine cmd = parser.parse(CommandLineApp.buildOptions(), argsa);
            StringBuilder stringBuilder = new StringBuilder();
            new CommandLineApp(stringBuilder, cmd).extractTables(cmd);
            return stringBuilder.toString();
        } catch (Exception e) {
            log.error("读取PDF错误:{}", e.getMessage());
        }
        return null;
    }

    /**
     * 读取PDF方法
     *
     * @param conversionType -f导出格式,默认CSV  (一定要大写)
     * @param pageNo         -p 指导出哪页,all是所有
     * @param filePath       文件路径
     * @param modeType       读取类型
     * @return -l 强制使用点阵模式提取PDF　（关键在于这儿）
     */
    public static String readPDFcontentByFilePath(String conversionType, String pageNo, String filePath, String modeType) {
        if (Objects.isNull(conversionType)) {
            conversionType = "JSON";
        }
        if (Objects.isNull(pageNo)) {
            pageNo = "all";
        }
        if (Objects.isNull(modeType)) {
            modeType = "l";
        }
        try {
            String[] argsa = new String[]{"-f=" + conversionType, "-p=" + pageNo, filePath, "-" + modeType};
            CommandLineParser parser = new DefaultParser();
            CommandLine cmd = parser.parse(CommandLineApp.buildOptions(), argsa);
            StringBuilder stringBuilder = new StringBuilder();
            new CommandLineApp(stringBuilder, cmd).extractTables(cmd);
            return stringBuilder.toString();
        } catch (Exception e) {
            log.error("读取PDF错误:{}", e.getMessage());
        }
        return null;
    }


}


//    public String readPDF2(String fileName) {
//        String result = "";
//        File file = new File(fileName);
//        FileInputStream in = null;
//        try {
//            in = new FileInputStream(fileName);
//            // 新建一个PDF解析器对象
//            PDFParser parser = new PDFParser((RandomAccessRead) new RandomAccessFile(file, "rw"));
//            // 对PDF文件进行解析
//            parser.parse();
//            // 获取解析后得到的PDF文档对象
//            PDDocument pdfdocument = parser.getPDDocument();
//            // 新建一个PDF文本剥离器
//            PDFTextStripper stripper = new PDFTextStripper();
//            stripper.setSortByPosition(false); //sort:设置为true 则按照行进行读取，默认是false
//            // 从PDF文档对象中剥离文本
//            result = stripper.getText(pdfdocument);
//        } catch (Exception e) {
//            System.out.println("读取PDF文件" + file.getAbsolutePath() + "生失败！" + e);
//            e.printStackTrace();
//        } finally {
//            if (in != null) {
//                try {
//                    in.close();
//                } catch (IOException e1) {
//                }
//            }
//        }
//        return result;
//    }

